#!/usr/bin/env python
#
# Copyright 2005 Free Software Foundation, Inc.
# 
# This file is part of GNU Radio
# 
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
# 
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
# 

"""
Digital voice Tx and Rx using GSM 13kbit vocoder and GMSK.

Runs channel at 32kbit/sec.
"""

from gnuradio import gr, gru
from gnuradio import blocks
from gnuradio.blksimpl.gmsk import gmsk_mod, gmsk_demod

from gnuradio.vocoder import gsm_full_rate

# Size of gsm full rate speech encoder output packet in bytes

GSM_FRAME_SIZE = 33

# Size of packet in bytes that we send to GMSK modulator:
#
# Target: 256kS/sec air rate.
#
#  256kS  1 sym   1 bit   1 byte   0.020 sec   80 bytes
#  ---- * ----- * ----- * ------ * --------- = --------
#  sec    8 S     1 sym   8 bits     frame      frame
#
# gr_simple_framer add 10 bytes of overhead.

AIR_FRAME_SIZE = 70


class digital_voice_tx(gr.hier_block):
    """
    Hierarchical block for digital voice transmission.

    The input is 8kS/sec floating point audio in the range [-1,+1]
    The output is 256kS/sec GMSK modulated complex baseband signal in the range [-1,+1].
    """
    def __init__(self, fg):
        samples_per_symbol = 8
        symbol_rate = 32000
        bt = 0.3                # Gaussian filter bandwidth * symbol time

        src_scale = blocks.multiply_const_ff(32767)
        f2s = blocks.float_to_short()
        voice_coder = gsm_full_rate.encode_sp()

        channel_coder = gr.multiply_const_b(1)
        p2s = gr.parallel_to_serial(gr.sizeof_char, AIR_FRAME_SIZE)

        mod = gmsk_mod(fg, sps=samples_per_symbol,
                       symbol_rate=symbol_rate, bt=bt,
                       p_size=AIR_FRAME_SIZE)

        fg.connect(src_scale, f2s, voice_coder, channel_coder, p2s, mod)
        gr.hier_block.__init__(self, fg, src_scale, mod)


class digital_voice_rx(gr.hier_block):
    """
    Hierarchical block for digital voice reception.

    The input is 256kS/sec GMSK modulated complex baseband signal.
    The output is 8kS/sec floating point audio in the range [-1,+1]
    """
    def __init__(self, fg):
        samples_per_symbol = 8
        symbol_rate = 32000

        demod = gmsk_demod(fg, sps=samples_per_symbol,
                           symbol_rate=symbol_rate, 
                           p_size=AIR_FRAME_SIZE)

        s2p = gr.serial_to_parallel(gr.sizeof_char, AIR_FRAME_SIZE)
        channel_decoder = gr.multiply_const_b(1)

        voice_decoder = gsm_full_rate.decode_ps()
        s2f = blocks.short_to_float ()
        sink_scale = blocks.multiply_const_ff(1.0/32767.)

        fg.connect(demod, s2p, channel_decoder, voice_decoder, s2f, sink_scale)
        gr.hier_block.__init__(self, fg, demod, sink_scale)
